package com.ruoyi.filter;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.houbb.sensitive.word.api.IWordData;
import com.github.houbb.sensitive.word.api.IWordDeny;
import com.github.houbb.sensitive.word.bs.SensitiveWordBs;
import com.github.houbb.sensitive.word.core.SensitiveWordHelper;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.domain.T06;
import com.ruoyi.domain.T18;
import com.ruoyi.domain.T22;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.service.IT06Service;
import com.ruoyi.service.IT18Service;
import com.ruoyi.service.IT22Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/***
 * 敏感词过滤器
 */
@Component
@Slf4j
public class SensitiveWordFilter implements Filter {

    @Autowired
    private TokenService tokenService;
    @Autowired
    private IT06Service t06Service;

    @Value("${sensitive.searchUrl}")
    private List<String> searchUrl;
    @Value("${sensitive.ingoreUrl}")
    private List<String> ingoreUrl;

    /**
     * 验证请求url与配置的url是否匹配的工具类
     */
    private AntPathMatcher pathMatcher = new AntPathMatcher();

    @Resource
    private ObjectMapper objectMapper; // springmvc启动时自动装配json处理类
    @Autowired
    private final SensitiveWordBs sensitiveWordBs;

    @Autowired
    private IT18Service t18Service;




    @Autowired
    private IT22Service t22Service;

    public SensitiveWordFilter(SensitiveWordBs sensitiveWordBs) {
        this.sensitiveWordBs = sensitiveWordBs;
    }



    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 可以在这里进行一些初始化操作
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        String url = ((HttpServletRequest) request).getRequestURI();
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        log.info("---------------------------->请求开始过滤");
        log.info(httpRequest.getContentType());
        System.out.println(httpRequest.getContentType());

        // 检查是否为文件上传请求
        if (!ObjectUtils.isEmpty(httpRequest.getContentType())) {
            if (httpRequest.getContentType().contains("multipart/form-data")) {
                chain.doFilter(request, response);
                System.out.println("---------------------------->multipart/form-data");
                return; // 确保文件上传请求只被处理一次
            }
        }

        AtomicReference<Boolean> isIngore = new AtomicReference<>(false);
        for (String s : ingoreUrl) {
            if (pathMatcher.match(s, url)) {
                isIngore.set(true);
                break;
            }
        }
        if (isIngore.get()) { // 忽略地址，跳过处理
            chain.doFilter(request, response);
        } else {
            AtomicReference<Boolean> isSearch = new AtomicReference<>(false);
            for (String s : searchUrl) {
                log.info("---------------------------->检测url：" + s);
                if (pathMatcher.match(s, ((HttpServletRequest) request).getRequestURI())) {
                    log.info("---------------------------->需要过滤");
                    isSearch.set(true);
                    break;
                }
            }
            if (isSearch.get()) { // 搜索请求，直接返回错误
                String getParam = getGetParameters((HttpServletRequest) request);
                List<String> getWord = sensitiveWordBs.findAll(getParam);
                log.info("---------------------------->get参数开始过滤" + getParam);
                if (getWord.size() > 0) {
                    log.info("---------------------------->查找到了敏感词");
                    httpResponse.setStatus(HttpServletResponse.SC_OK);
                    httpResponse.setContentType("application/json;charset=UTF-8");
                    Map<String, String> rsp = new HashMap<>();
                    rsp.put("code", "400");
                    rsp.put("msg", "请求包含敏感词，请检查后重试。");
                    httpResponse.getWriter().write(objectMapper.writeValueAsString(rsp));
                    return;
                } else {
                    String postParam = getPostParameters((HttpServletRequest) request);
                    log.info("---------------------------->post参数开始过滤：" + postParam);

                    HttpServletRequest request1 = (HttpServletRequest) request;

                    getSenWord(request1,1);

                    List<String> postWord = sensitiveWordBs.findAll(postParam);
                    if (postWord.size() > 0) {
                        httpResponse.setStatus(HttpServletResponse.SC_OK);
                        httpResponse.setContentType("application/json;charset=UTF-8");
                        Map<String, String> rsp = new HashMap<>();
                        rsp.put("code", "400");
                        rsp.put("msg", "请求包含敏感词，请检查后重试。");
                        httpResponse.getWriter().write(objectMapper.writeValueAsString(rsp));
                        return;
                    }
                }
                chain.doFilter(request, response);
            } else { // 其他的存储接口
                SensitiveRequestWrapper wrapper = new SensitiveRequestWrapper(httpRequest, sensitiveWordBs);
                chain.doFilter(wrapper, response);
            }
        }
    }


    public String getGetParameters(HttpServletRequest request) {
        StringBuilder response = new StringBuilder();
        // 使用 getParameterMap 获取所有参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            String paramName = entry.getKey();
            String[] paramValues = entry.getValue();
            for (String value : paramValues) {
                response.append(value).append(" ");
            }
        }
        return response.toString();
    }

    public String getPostParameters(HttpServletRequest request) {
        StringBuilder response = new StringBuilder();
        String contentType = request.getContentType();

        if (contentType != null && contentType.contains("application/json")) {
            try (BufferedReader reader = request.getReader()) {
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
            } catch (IOException e) {
                log.error("Error reading JSON request body", e);
            }
        } else if (contentType != null && contentType.contains("application/x-www-form-urlencoded")) {
            Map<String, String[]> parameterMap = request.getParameterMap();
            for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
                String[] paramValues = entry.getValue();
                for (String value : paramValues) {
                    response.append(value).append(" ");
                }
            }
        }
        return response.toString();
    }

//    public void replaceGetParameters(HttpServletRequest request) {
//        StringBuilder response = new StringBuilder();
//        // 使用 getParameterMap 获取所有参数
//        Map<String, String[]> parameterMap = request.getParameterMap();
//        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
//            String paramName = entry.getKey();
//            String[] paramValues = entry.getValue();
//            for (String value : paramValues) {
//                SensitiveWordHelper.replace(value, '*');
//            }
//        }
//
//    }

//    public void repalcePostParameters(HttpServletRequest request) {
//        StringBuilder response = new StringBuilder();
//        // 使用 getParameterMap 获取所有参数
//        Map<String, String[]> parameterMap = request.getParameterMap();
//        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
//            String paramName = entry.getKey();
//            String[] paramValues = entry.getValue();
//            for (String value : paramValues) {
//                SensitiveWordHelper.replace(value, '*');
//            }
//        }
//    }

    @Override
    public void destroy() {
        // 清理资源
    }



    public void getSenWord(HttpServletRequest request, int type){
        //说明是项目启动时的敏感词过滤
        if(type == 1){
            String str = "%T3@#5fG8$9Lq!7Zx&2Qd*1Rt^4Wn(6Eh)~Vj+8K書官方s-0Pm=3Bc{9Nv}2Hg[7Dp讀書]1Aqdejgfrweh供熱:5Tf;4Rw'6Yk2Sd/9Lm8Jh|0Gv?3Bn";
            if (ObjectUtils.isEmpty(sensitiveWordBs.findAll(str))) {
                LoginUser loginUser = tokenService.getLoginUser(request);
                Long userId = loginUser.getUserId();
                T06 t06 = t06Service.selectT06ByF0601(userId);

                T22 t22 = new T22();
                t22.setF0301(t06.getF0301());
                List<T22> sensitiveWordLibs = t22Service.findAllByF0301((t06.getF0301()));
                List<String> list = sensitiveWordLibs.stream().map(s -> s.getWord()).collect(Collectors.toList());
                list.add(str);
                sensitiveWordBs.addWord(list);
            }
        }else {
            LoginUser loginUser = tokenService.getLoginUser(request);
            Long userId = loginUser.getUserId();
            T18 t18 = t18Service.selectT18ByF1801(userId);
            T22 t22 = new T22();
            t22.setF0301(t18.getF0301());
            List<T22> sensitiveWordLibs = t22Service.findAllByF0301((t18.getF0301()));
            List<String> list = sensitiveWordLibs.stream().map(s -> s.getWord()).collect(Collectors.toList());

            sensitiveWordBs.destroy();


            sensitiveWordBs.addWord(list);
        }
    }
}
